using System;
using System.Collections.Generic;
using System.Text;

namespace DacTaHinhThuc
{
    /// <summary>
    /// class de luu bracket cung voi vi tri cua no
    /// </summary>
    class Braket_Pos
    {
        public int IsBraket;
        public int iPos;
        public Braket_Pos()
        {
            this.IsBraket = this.iPos = 0;
        }
    };

    /// <summary>
    /// class bieu thuc
    /// </summary>
    class Expression
    {
        private string strExpression;
        private char[] listOpenBracket = { '{', '[', '(' };
        private char[] listCloseBracket = { '}', ']', ')' };

        /// <summary>
        /// contructor khong co tham so
        /// </summary>
        public Expression() { }

        /// <summary>
        /// contructor 1 tham so
        /// </summary>
        /// <param name="str"></param>
        public Expression(string str)
        {
            this.strExpression = str;
        }


        /// <summary>
        /// Kiem tra loai ky tu co la dau ngoac hay khong
        /// </summary>
        /// <param name="c"></param>
        /// <returns>
        /// tra ve Braket_Pos gom co la dau ngoac hay khong cung voi vi tri cua no
        /// </returns>
        private Braket_Pos IsBraket(char c)
        {
            Braket_Pos tmp = new Braket_Pos();
            int i;
            for (i = 0; i < listOpenBracket.Length; i++)
            {
                if (c == listOpenBracket[i])
                {
                    tmp.IsBraket = 1;
                    tmp.iPos = i;
                    return tmp;
                }
            }
            for (i = 0; i < listCloseBracket.Length; i++)
            {
                if (c == listCloseBracket[i])
                {
                    tmp.IsBraket = 2;
                    tmp.iPos = i;
                    return tmp;
                }
            }
            tmp.iPos = -1;
            tmp.IsBraket = 0;
            return tmp;
        }

        /// <summary>
        /// Kiem tra bieu thuc co hop le hay khong
        /// </summary>
        /// <returns>
        /// true: neu bieu thuc hop le
        /// false: neu bieu thuc khong hop le
        /// </returns>
        public bool Check()
        {
            Stack<Braket_Pos> stack;
            stack = new Stack<Braket_Pos>();

            int i;
            for (i = 0; i < strExpression.Length; i++)
            {
                Braket_Pos tmp = new Braket_Pos();
                tmp = IsBraket(strExpression[i]);
                switch (tmp.IsBraket)
                {
                    case 1:
                        stack.Push(tmp);
                        break;
                    case 2:
                        if (stack.Count > 0)
                        {
                            Braket_Pos charBefore = stack.Pop();
                            if (charBefore.iPos != tmp.iPos)
                            {
                                return false;
                            }
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    default:
                        break;
                }
            }
            if (stack.Count == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    /// <summary>
    /// class de kiem tra cac dieu kien
    /// </summary>
    class Checking
    {
        /// <summary>
        /// ham de kiem tra 1 bieu thuc xem co dong mo ngoac hop le hay khong
        /// </summary>
        /// <param name="str">bieu thuc can kiem tra</param>
        /// <returns>true: hop le
        /// false: khong hop le</returns>
        public static bool CheckBraket(string str)
        {
            Expression expression = new Expression(str);
            return expression.Check();
        }

        /// <summary>
        /// kiem tra tinh hop le cua cac tham so, co trung ten hay ko? ...
        /// </summary>
        /// <param name="arrPara">danh sach cac tham so can kiem tra</param>
        /// <returns>tra ve index cua tham so co ten bi trung, hoac tra ve -1 neu tat ca cac tham so deu hop le</returns>
        public static int CheckSameParameter(Parameter[] arrPara)
        {
            int i;
            int j;
            for (i = 0; i < arrPara.Length - 1; i++)
            {
                for (j = i + 1; j < arrPara.Length; j++)
                {
                    if (arrPara[i].Name == arrPara[j].Name)
                    {
                        return j;
                    }
                }
            }
            return -1;
        }

        /// <summary>
        /// kiem tra xem cac tham so co duoc dat ten dung theo qui tac hay khong
        /// </summary>
        /// <param name="arrPara">danh sach cac tham so can kiem tra</param>
        /// <returns>tra ve index cua tham so co ten duoc dat khong hop le, hoac tra ve -1 neu tat ca cac tham so deu hop le</returns>
        public static int CheckNameParameter(Parameter[] arrPara)
        {
            DFA dfa = new DFA();
            int i;
            for (i = 0; i < arrPara.Length; i++)
            {
                //dung DFA de kiem tra
                if (!dfa.CheckString(arrPara[i].Name))
                {
                    return i;
                }
            }
            return -1;
        }               

        /// <summary>
        /// ham kiem tra ten cua ham co hop le hay khong
        /// </summary>
        /// <param name="nameFunc">ten ham can kiem tra</param>
        /// <returns>
        /// true: dung
        /// false: sai
        /// </returns>
        public static bool CheckNameFunction(string nameFunc)
        {
            DFA dfa = new DFA();
            return dfa.CheckString(nameFunc);
        }
    }
}
